using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using JGSY.CMS.LowCode.Platform.Infrastructure.Configuration.Configuration.Models;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration
{
    /// <summary>
    /// 配置管理服务接口
    /// 提供对各种配置项的强类型访问和管理
    /// </summary>
    public interface IConfigurationService
    {
        /// <summary>
        /// 获取数据库配置
        /// </summary>
        /// <returns>数据库配置</returns>
        DatabaseConfig GetDatabaseConfig();

        /// <summary>
        /// 获取 JWT 配置
        /// </summary>
        /// <returns>JWT配置</returns>
        JwtConfig GetJwtConfig();

        /// <summary>
        /// 获取缓存配置
        /// </summary>
        /// <returns>缓存配置</returns>
        CacheConfig GetCacheConfig();

        /// <summary>
        /// 获取安全配置
        /// </summary>
        /// <returns>安全配置</returns>
        SecurityConfig GetSecurityConfig();

        /// <summary>
        /// 获取 CORS 配置
        /// </summary>
        /// <returns>CORS配置</returns>
        CorsConfig GetCorsConfig();

        /// <summary>
        /// 获取文件上传配置
        /// </summary>
        /// <returns>文件上传配置</returns>
        FileUploadConfig GetFileUploadConfig();

        /// <summary>
        /// 获取日志配置
        /// </summary>
        /// <returns>日志配置</returns>
        LoggingConfig GetLoggingConfig();

        /// <summary>
        /// 获取指定连接字符串
        /// </summary>
        /// <param name="name">连接字符串名称</param>
        /// <returns>连接字符串</returns>
        string GetConnectionString(string name);

        /// <summary>
        /// 获取当前数据库类型对应的连接字符串
        /// </summary>
        /// <returns>当前数据库连接字符串</returns>
        string GetCurrentDatabaseConnectionString();

        /// <summary>
        /// 获取应用程序基础配置信息
        /// </summary>
        /// <returns>基础配置信息字典</returns>
        IDictionary<string, object> GetAppInfo();

        /// <summary>
        /// 获取环境变量值
        /// </summary>
        /// <param name="name">环境变量名称</param>
        /// <param name="defaultValue">默认值</param>
        /// <returns>环境变量值</returns>
        string GetEnvironmentVariable(string name, string defaultValue = "");

        /// <summary>
        /// 是否为开发环境
        /// </summary>
        /// <returns>是否为开发环境</returns>
        bool IsDevelopment();

        /// <summary>
        /// 是否为生产环境
        /// </summary>
        /// <returns>是否为生产环境</returns>
        bool IsProduction();

        /// <summary>
        /// 获取当前环境名称
        /// </summary>
        /// <returns>环境名称</returns>
        string GetEnvironmentName();
    }

    /// <summary>
    /// 配置管理服务实现
    /// </summary>
    public class ConfigurationService : IConfigurationService
    {
        private readonly IAppSettingsManager _appSettingsManager;
        private readonly ILogger<ConfigurationService> _logger;
        private readonly Dictionary<Type, object> _configCache = new Dictionary<Type, object>();

        public ConfigurationService(IAppSettingsManager appSettingsManager, ILogger<ConfigurationService> logger)
        {
            _appSettingsManager = appSettingsManager ?? throw new ArgumentNullException(nameof(appSettingsManager));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        /// <summary>
        /// 获取数据库配置
        /// </summary>
        public DatabaseConfig GetDatabaseConfig()
        {
            return GetCachedConfig(() =>
            {
                var config = new DatabaseConfig
                {
                    Type = _appSettingsManager.GetStringValue("DatabaseType", "SqlServer"),
                    ConnectionTimeout = _appSettingsManager.GetIntValue("Database:ConnectionTimeout", 30),
                    CommandTimeout = _appSettingsManager.GetIntValue("Database:CommandTimeout", 120),
                    EnableSensitiveDataLogging = _appSettingsManager.GetBoolValue("Database:EnableSensitiveDataLogging", false)
                };

                // 根据数据库类型设置连接字符串
                config.ConnectionString = config.Type.ToLower() switch
                {
                    "sqlserver" => _appSettingsManager.GetConnectionString("SqlServer"),
                    "mysql" => _appSettingsManager.GetConnectionString("MySql"),
                    "postgres" => _appSettingsManager.GetConnectionString("Postgres"),
                    "sqlite" => _appSettingsManager.GetConnectionString("Sqlite"),
                    _ => _appSettingsManager.GetConnectionString("SqlServer")
                };

                return config;
            });
        }

        /// <summary>
        /// 获取 JWT 配置
        /// </summary>
        public JwtConfig GetJwtConfig()
        {
            return GetCachedConfig(() => _appSettingsManager.GetSection<JwtConfig>("Security:Jwt"));
        }

        /// <summary>
        /// 获取缓存配置
        /// </summary>
        public CacheConfig GetCacheConfig()
        {
            return GetCachedConfig(() => _appSettingsManager.GetSection<CacheConfig>("Cache"));
        }

        /// <summary>
        /// 获取安全配置
        /// </summary>
        public SecurityConfig GetSecurityConfig()
        {
            return GetCachedConfig(() => _appSettingsManager.GetSection<SecurityConfig>("Security"));
        }

        /// <summary>
        /// 获取 CORS 配置
        /// </summary>
        public CorsConfig GetCorsConfig()
        {
            return GetCachedConfig(() => _appSettingsManager.GetSection<CorsConfig>("Cors"));
        }

        /// <summary>
        /// 获取文件上传配置
        /// </summary>
        public FileUploadConfig GetFileUploadConfig()
        {
            return GetCachedConfig(() => _appSettingsManager.GetSection<FileUploadConfig>("Upload"));
        }

        /// <summary>
        /// 获取日志配置
        /// </summary>
        public LoggingConfig GetLoggingConfig()
        {
            return GetCachedConfig(() => _appSettingsManager.GetSection<LoggingConfig>("Logging"));
        }

        /// <summary>
        /// 获取指定连接字符串
        /// </summary>
        public string GetConnectionString(string name)
        {
            return _appSettingsManager.GetConnectionString(name);
        }

        /// <summary>
        /// 获取当前数据库类型对应的连接字符串
        /// </summary>
        public string GetCurrentDatabaseConnectionString()
        {
            var dbConfig = GetDatabaseConfig();
            return dbConfig.ConnectionString;
        }

        /// <summary>
        /// 获取应用程序基础配置信息
        /// </summary>
        public IDictionary<string, object> GetAppInfo()
        {
            return new Dictionary<string, object>
            {
                ["Environment"] = GetEnvironmentName(),
                ["DatabaseType"] = _appSettingsManager.GetStringValue("DatabaseType", "Unknown"),
                ["CacheType"] = _appSettingsManager.GetStringValue("Cache:Type", "memory"),
                ["JwtIssuer"] = _appSettingsManager.GetStringValue("Security:Jwt:Issuer", ""),
                ["AllowedHosts"] = _appSettingsManager.GetStringValue("AllowedHosts", "*"),
                ["Version"] = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "1.0.0"
            };
        }

        /// <summary>
        /// 获取环境变量值
        /// </summary>
        public string GetEnvironmentVariable(string name, string defaultValue = "")
        {
            return Environment.GetEnvironmentVariable(name) ?? defaultValue;
        }

        /// <summary>
        /// 是否为开发环境
        /// </summary>
        public bool IsDevelopment()
        {
            return GetEnvironmentName().Equals("Development", StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// 是否为生产环境
        /// </summary>
        public bool IsProduction()
        {
            return GetEnvironmentName().Equals("Production", StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// 获取当前环境名称
        /// </summary>
        public string GetEnvironmentName()
        {
            return GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Production");
        }

        /// <summary>
        /// 获取缓存的配置对象
        /// </summary>
        /// <typeparam name="T">配置类型</typeparam>
        /// <param name="factory">配置工厂方法</param>
        /// <returns>配置对象</returns>
        private T GetCachedConfig<T>(Func<T> factory) where T : class
        {
            var type = typeof(T);
            if (!_configCache.TryGetValue(type, out var cached))
            {
                try
                {
                    cached = factory();
                    _configCache[type] = cached;
                    _logger.LogDebug("Configuration cached for type: {Type}", type.Name);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error getting configuration for type: {Type}", type.Name);
                    cached = Activator.CreateInstance<T>();
                    _configCache[type] = cached;
                }
            }
            return (T)cached;
        }
    }
}
